package com.zhihaihe.file.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qiwenshare.common.constant.FileConstant;
import com.zhihaihe.file.mapper.UserFileMapper;
import com.zhihaihe.file.pojo.RecoveryFile;
import com.zhihaihe.file.pojo.UserFileBean;
import com.zhihaihe.file.service.IFileService;
import com.zhihaihe.file.service.IUserFileService;
import com.zhihaihe.file.util.DateUtil;
import com.zhihaihe.file.util.ThreadUtils;
import com.zhihaihe.file.vo.file.FileListVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;


@Slf4j
@Service
@AllArgsConstructor
public class UserFileServiceImpl extends ServiceImpl<UserFileMapper, UserFileBean> implements IUserFileService {

    private UserFileMapper userFileMapper;

    private IFileService fileService;

    public static Executor executor = Executors.newFixedThreadPool(20);


    @Override
    public boolean isDirExist(String fileName, String filePath, Long userId) {
        LambdaQueryWrapper<UserFileBean> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserFileBean::getFileName, fileName)
                .eq(UserFileBean::getFilePath, filePath)
                .eq(UserFileBean::getUserId, userId)
                .eq(UserFileBean::getDeleteFlag, 0)
                .eq(UserFileBean::getIsDir, 1);
        List<UserFileBean> list = userFileMapper.selectList(lambdaQueryWrapper);
        if (list != null && !list.isEmpty()) {
            return true;
        }
        return false;
    }

    @Override
    public List<UserFileBean> selectUserFileByNameAndPath(String fileName, String filePath, Long userId) {
        LambdaQueryWrapper<UserFileBean> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(UserFileBean::getFileName, fileName)
                .eq(UserFileBean::getFilePath, filePath)
                .eq(UserFileBean::getUserId, userId)
                .eq(UserFileBean::getDeleteFlag, 0);
        return userFileMapper.selectList(lambdaQueryWrapper);
    }

    @Override
    public void replaceUserFilePath(String filePath, String oldFilePath, Long userId) {
        userFileMapper.replaceFilePath( filePath,  oldFilePath,  userId);
    }

    @Override
    public List<FileListVo> userFileList(UserFileBean userFile, Long beginCount, Long pageCount) {
        return userFileMapper.userFileList(userFile,beginCount,pageCount);
    }

    @Override
    public void deleteUserFile(Long userFileId, Long userId) {
        UserFileBean userFile = userFileMapper.selectById(userFileId);
        String uuid = UUID.randomUUID().toString();
        if (userFile.getIsDir() == 1) {
            LambdaUpdateWrapper<UserFileBean> userFileLambdaUpdateWrapper = new LambdaUpdateWrapper<UserFileBean>();
            userFileLambdaUpdateWrapper.set(UserFileBean::getDeleteFlag,ThreadUtils.getRandomInt())
                    .set(UserFileBean::getDeleteBatchNum, uuid)
                    .set(UserFileBean::getDeleteTime, com.qiwenshare.common.util.DateUtil.getCurrentTime())
                    .eq(UserFileBean::getUserFileId, userFileId);
            userFileMapper.update(null, userFileLambdaUpdateWrapper);

            String filePath = userFile.getFilePath() + userFile.getFileName() + "/";
            updateFileDeleteStateByFilePath(filePath, uuid, userId);

        }else{
            UserFileBean userFileTemp = userFileMapper.selectById(userFileId);
            LambdaUpdateWrapper<UserFileBean> userFileLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            userFileLambdaUpdateWrapper.set(UserFileBean::getDeleteFlag, ThreadUtils.getRandomInt())
                    .set(UserFileBean::getDeleteTime, com.qiwenshare.common.util.DateUtil.getCurrentTime())
                    .set(UserFileBean::getDeleteBatchNum, uuid)
                    .eq(UserFileBean::getUserFileId, userFileTemp.getUserFileId());
            userFileMapper.update(null, userFileLambdaUpdateWrapper);
        }

        RecoveryFile recoveryFile = new RecoveryFile();
        recoveryFile.setUserFileId(userFileId);
        recoveryFile.setDeleteTime(com.qiwenshare.common.util.DateUtil.getCurrentTime());
        recoveryFile.setDeleteBatchNum(uuid);
    }


    @Override
    public List<UserFileBean> selectFileListLikeRightFilePath(String filePath, long userId) {
        filePath = filePath.replace("\\", "\\\\\\\\");
        filePath = filePath.replace("'", "\\'");
        filePath = filePath.replace("%", "\\%");
        filePath = filePath.replace("_", "\\_");

        LambdaQueryWrapper<UserFileBean> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        log.info("查询文件路径：" + filePath);

        lambdaQueryWrapper.eq(UserFileBean::getUserId, userId)
                .likeRight(UserFileBean::getFilePath, filePath)
                .eq(UserFileBean::getDeleteFlag, 0);
        return userFileMapper.selectList(lambdaQueryWrapper);
    }

    /**
     * 修改文件删除状态
     * @param filePath 文件路径
     * @param deleteBatchNum 文件删除批次
     * @param userId 用户id
     */
    private void updateFileDeleteStateByFilePath(String filePath, String deleteBatchNum, Long userId) {
        executor.execute(() -> {
            List<UserFileBean> fileList = selectFileListLikeRightFilePath(filePath, userId);
            for (int i = 0; i < fileList.size(); i++){
                UserFileBean userFileTemp = fileList.get(i);
                //标记删除标志
                LambdaUpdateWrapper<UserFileBean> userFileLambdaUpdateWrapper1 = new LambdaUpdateWrapper<>();
                userFileLambdaUpdateWrapper1.set(UserFileBean::getDeleteFlag, ThreadUtils.getRandomInt())
                        .set(UserFileBean::getDeleteTime, DateUtil.getCurrentTime())
                        .set(UserFileBean::getDeleteBatchNum, deleteBatchNum)
                        .eq(UserFileBean::getUserFileId, userFileTemp.getUserFileId())
                        .eq(UserFileBean::getDeleteFlag, 0);
                userFileMapper.update(null, userFileLambdaUpdateWrapper1);
            }
        });
    }


    @Override
    public List<FileListVo> selectFileNotInExtendNames(List<String> arrList, Long beginCount, long pageCount, long userId) {
        return userFileMapper.selectFileNotInExtendNames(arrList, beginCount, pageCount, userId);
    }

    @Override
    public Long selectCountNotInExtendNames(List<String> fileNameList, Long beginCount, long pageCount, long userId) {
        return userFileMapper.selectCountNotInExtendNames(fileNameList, beginCount, pageCount, userId);
    }

    @Override
    public List<FileListVo> selectFileByExtendName(List<String> fileExtendsByType, Long beginCount, long pageCount, long userId) {
        return userFileMapper.selectFileByExtendName(fileExtendsByType, beginCount, pageCount, userId);
    }

    @Override
    public Long selectCountByExtendName(List<String> fileExtendsByType, Long beginCount, long pageCount, long userId) {
        return userFileMapper.selectCountByExtendName(fileExtendsByType, beginCount, pageCount, userId);
    }
}
